﻿using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Image = System.Windows.Controls.Image;
using System.Windows.Threading;
using System.Drawing;

namespace SuperFrame.Charts
{
    public abstract class SeriesContainer : DependencyObject
    {
        internal Image sourceImage;
        internal Graphics GDIGraphics;
        internal InteropBitmap InteropBitmap;
        internal WriteableBitmap WritableBitmap;
        internal Bitmap ImageBitmap;
        internal Graphics WritableBitmapGraphics;
        internal double dpiFactor;
        internal Canvas PartsCanvas;
        internal ContainerCollection collection;

        public BaseSeries Series
        {
            get { return (BaseSeries)GetValue(SeriesProperty); }
            set { SetValue(SeriesProperty, value); }
        }
        public static readonly DependencyProperty SeriesProperty =DependencyProperty.Register("Series", typeof(BaseSeries), typeof(SeriesContainer), new PropertyMetadata(null));

        public RenderingMode RenderingMode
        {
            get { return (RenderingMode)GetValue(RenderingModeProperty); }
            set { SetValue(RenderingModeProperty, value); }
        }
        public static readonly DependencyProperty RenderingModeProperty = DependencyProperty.Register("RenderingMode", typeof(RenderingMode), typeof(SeriesContainer), new PropertyMetadata(RenderingMode.Default));

        public ContainerCollection Container
        {
            get { return (ContainerCollection)GetValue(ContainerProperty); }
            set { SetValue(ContainerProperty, value); }
        }
        public static readonly DependencyProperty ContainerProperty = DependencyProperty.Register("Container", typeof(ContainerCollection), typeof(SeriesContainer), new PropertyMetadata(null));


        public SeriesContainer()
        {
            this.sourceImage = new Image() { Stretch = Stretch.None };
            PartsCanvas = new Canvas();
        }

        public void Clear()
        {
            try
            {
                switch (RenderingMode)
                {
                    case RenderingMode.GDIRendering:
                        if (GDIGraphics != null)
                            GDIGraphics.Clear(Colors.Transparent.AsDrawingColor());
                        break;
                    case RenderingMode.WritableBitmap:
                        if (WritableBitmapGraphics != null)
                            WritableBitmapGraphics.Clear(Colors.Transparent.AsDrawingColor());
                        break;
                    case RenderingMode.Default:
                        PartsCanvas.Children.Clear();
                        break;
                    default:
                        break;
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine("发生异常 : " + e.Message);
            }
        }

        private bool _isBitmapInitialized;
        public bool IsBitmapInitialized
        {
            get { return _isBitmapInitialized; }
            set { _isBitmapInitialized = value; }
        }

        public void Invalidate()
        {
            switch (RenderingMode)
            {
                case RenderingMode.GDIRendering:
                    if (this.InteropBitmap != null && this.GDIGraphics != null)
                        this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(delegate
                        {
                            Draw();
                        }));

                    break;
                case RenderingMode.WritableBitmap:
                    if (this.WritableBitmap != null && this.WritableBitmapGraphics != null)
                        this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(delegate
                        {
                            Draw();
                        }));
                    break;
                case RenderingMode.Default:
                    this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(delegate
                    {
                        Draw();
                    }));
                    break;
                default:
                    break;
            }

        }
        public virtual void Draw()
        {
            if (this.Series.Index == 0)
                Clear();

            var brush = this.Series.Stroke.AsDrawingBrush();
            var pen = new System.Drawing.Pen(brush, (float)this.Series.StrokeThickness);

            switch (this.RenderingMode)
            {
                case RenderingMode.GDIRendering:
                    if (Series != null)
                        DrawPath(Series, pen);
                    break;
                case RenderingMode.WritableBitmap:
                    if (Series != null)
                        DrawPath(Series, pen);
                    break;
                case RenderingMode.Default:
                    Clear();
                    if (Series != null)
                        DrawPath(Series, pen);
                    break;

                default:
                    break;
            }
        }

        protected virtual void DrawPath(BaseSeries series, System.Drawing.Pen pen)
        {
        }
        protected virtual void OnRender()
        {
        }

        private int index;
        internal int Index
        {
            get { return index; }
            set { index = value; }
        }

    }
}
